/****************************************************************************
 * uart.c
 *
 * 	 Copyright (C) Hiklife. All rights reserved.
 *   Author: Lgx <lgx@hiklife.com>	2019-03
 * 
 *  uart处理函数
 *
 ****************************************************************************/
#include "main.h"

//回调的数据包处理函数


/* ！！！！！！！！！！！！！！！！！！！！！！！！*/
/* ！！！要用这些函数各UART中断优先级必须一样！！！*/
/* ！！！！！！！！！！！！！！！！！！！！！！！！*/

/****************************************
 * 函数名：	uart_send_byte 
 * 说明：	uart发送，写入sbuf
 * 			非中断中掉用时需要确保发送中断不会发生，因为不可重入！
 * 输入：	id: uart id, da: 发送的数据
 * 输出：	--
 ****************************************/

/****************************************
 * 函数名：	uart_recv_byte 
 * 说明：	uart接收，读取sbuf
 * 输入：	id: uart id
 * 输出：	接收到的数据
 ****************************************/

/****************************************
 * 函数名：	set_rx_error 
 * 说明：	设置UART接收故障标志  
 * 输入：	id: uart id , f: true or false
 * 输出：	--
 ****************************************/
static void set_rx_error(u8 id, u8 f)
{
	if (id == ID_UART_PANEL)
    {
		// if((comm_rx_err == 0)&& f)
		
		comm_rx_err = f;
    }

	if (id == ID_UART_MOTOR)	
		motor_rx_err = f;
}

/* ！！！！！！！！！！！！！！！！！！！！！！！！*/
/* ！！！！！下面几个函数一般不需要修改 ！！！！！!*/
/* ！！！！！！！！！！！！！！！！！！！！！！！！*/

/****************************************
 * 函数名：	uart_packet_deal
 * 说明：	查询是否有一包数据要处理，调用process_packet包处理函数，及通讯故障计数
 * 			10ms调用一次
 * 输入：	UART_t 指针
 * 输出：	--
 ****************************************/
void uart_packet_deal(UART_t * c_uart)
{
	u8 len;
	u16 crc16_temp,crc16_recv;
	bool check;

	if(c_uart->recved_f)
	{
		
		if(c_uart->uart_id == ID_UART_PANEL)
		{			
			len = c_uart->rx_buf[4];
			crc16_temp = CRC16_MODBUS(c_uart->rx_buf,len-2);	
			crc16_recv = MAKEWORD(c_uart->rx_buf[len-1],c_uart->rx_buf[len-2]);						
			check = (crc16_temp == crc16_recv) ? 1 : 0;
		}
		else
		{
			len = 4;			
            check = verify_check_sum(c_uart->rx_buf,len);
		}

		if (check)
		{
            if((c_uart->rx_buf[0] == 0x5a)&&(c_uart->rx_buf[3] == 0xfc)&&(gu8_SystemBeginTime > 0))
            {  
				if(c_uart->uart_id == ID_UART_PANEL) 
				{            
					if(!(gb_TestFlag))
					{   
						                
						testUARTInit();
						TestCloseAllOut();                                     
						gb_TestFlag = 1;
						gu8_TestStateCnt = 0;
						gb_tcomd2 = 0; 
						buzz_start(BUZ_KEY);
					}
					gu8_TestRecved[0] = c_uart->rx_buf[5];
					gu8_TestRecved[1] = c_uart->rx_buf[6];
					gu8_TestRecved[2] = c_uart->rx_buf[7];    
					gu8_TestRecved[3] = c_uart->rx_buf[8];
					gu8_TestRecved[4] = c_uart->rx_buf[9];
					buzz_mode = c_uart->rx_buf[8]&0x0f;				             
					gu8_SystemBeginTime = 200;
				}
				c_uart->err_tmr_ct = 0;				
				c_uart->recved_f = false;
                c_uart->tosend_f = true;
                return;
            }            
			process_packet(c_uart);						//数据包处理

			/*********/
			c_uart->err_tmr_ct = 0;
			if (c_uart->err_clr_ct)
				c_uart->err_clr_ct--;
			else
				set_rx_error(c_uart->uart_id , 0);
			
			c_uart->recved_f = false;
			return;
		}
		else
		{//err
			c_uart->recved_f = false;
		}
	}
    if(c_uart->uart_id == ID_UART_MOTOR)
    {
        if((smoker.level == 0)&&(!gb_TestFlag))
            c_uart->err_tmr_ct = 0;
    }
    // if(gb_TestFlag)    
    // {
    //     if(c_uart->uart_id == ID_UART_PANEL)
    //         c_uart->err_tmr_ct = 0;
    // }        
	c_uart->err_tmr_ct++;
	if (c_uart->err_tmr_ct >= RX_ERR_TIME)
	{
		c_uart->err_clr_ct = RX_ERR_CLR;				//故障清除次数
		c_uart->err_tmr_ct = RX_ERR_TIME;
		set_rx_error(c_uart->uart_id , 1);				//本地接收故障
	}
}

/****************************************
 * 函数名：	uart_send_byte_isr
 * 说明：	一字节发送完成，发送下一个，发送中断中调用
 * 输入：	UART_t 指针
 * 输出：	--
 ****************************************/
void uart_send_byte_isr(UART_t * c_uart)
{
	u8 len;

	if (c_uart->sending_f)
	{//没有发送中断或发送中断有问题时，在循环中发送帧内数据

		len = c_uart->tx_buf[4];
		c_uart->tx_ct++;
		if (c_uart->tx_ct < len)
		{
			UART_SendByte(UART1, c_uart->tx_buf[c_uart->tx_ct]);
			c_uart->send_dly = 5;
			//uart_send_byte(c_uart->uart_id, c_uart->tx_buf[c_uart->tx_ct]); //51重入警告
		}
		else
		{
			c_uart->tx_ct = 0;
			c_uart->sending_f = false; 					//一帧数据发送完成
		}

		return;
 	}

    c_uart->tx_ct = 0;
}

void uart_send_byte_isr2(UART_t * c_uart)
{
	u8 len;

	if (c_uart->sending_f)
	{//没有发送中断或发送中断有问题时，在循环中发送帧内数据
		len = 4;						//*******

		c_uart->tx_ct++;
		if (c_uart->tx_ct < len)
		{
			EUART_SendByte(c_uart->tx_buf[c_uart->tx_ct]);		
			//uart_send_byte(c_uart->uart_id, c_uart->tx_buf[c_uart->tx_ct]); //51重入警告
		}
		else
		{

			c_uart->tx_ct = 0;
			c_uart->sending_f = false; 					//一帧数据发送完成
		}

		return;
 	}

    c_uart->tx_ct = 0;
}
/****************************************
 * 函数名：	uart_recv_byte_isr
 * 说明：	收到一个字节, 一般在中断中调用
 * 输入：	UART_t 指针
 * 输出：	--
 ****************************************/
void uart_recv_byte_isr(UART_t * c_uart)
{
	u8 uart_rx_data;
	u8 packet_len = 0;

	/* Receive one date */
	uart_rx_data = UART_RecByte(UART1);		//51重入
	
  	if(!c_uart->rx_byte_tmr) 							//收到一帧数据必须在超时时间内处理！！！
		  c_uart->rx_ct = 0;			                //last recv byte timeout! reset recv!!!
	c_uart->rx_byte_tmr = RX_RST_TIME;
	
	if (c_uart->recved_f)
		return;
 		
  	if(!c_uart->rx_ct)
  	{
  		if ((uart_rx_data != LEAD_BYTE)&& (uart_rx_data != LEAD_BYTETEST))
  			return;
	}
    if(!c_uart->rx_ct)
    {
  		if ((gu8_SystemBeginTime == 0)&&(uart_rx_data == LEAD_BYTETEST))//if((c_uart->rx_buf[0] == 0x5a)&&(c_uart->rx_buf[2] == 0xfc)&&(gu8_SystemBeginTime > 0))
  			return;        
    }
	if(c_uart->rx_ct == 4)
	{
		if ((uart_rx_data > UART_RX_BYTES) || (uart_rx_data < 2))
		{//err
			c_uart->rx_ct = 0;
			return;
		}
	}

	c_uart->rx_buf[c_uart->rx_ct] = uart_rx_data;
	c_uart->rx_ct++;	


	if (c_uart->rx_ct >= 5)
	{
		packet_len = c_uart->rx_buf[4];
	}		
	else
		return;

	if (c_uart->rx_ct >= packet_len)
	{
		c_uart->rx_ct = 0;   		//收到一帧
		c_uart->recved_f = true;    //isr_send_signal(CTRL_TASK_ID);给任务 CTRL_TASK_ID 发信号, 为了使用而使用		
	}
}

void uart_recv_byte_isr2(UART_t * c_uart)
{
	u8 uart_rx_data;
	u8 packet_len = 0;

	/* Receive one date */
	uart_rx_data = EUART_RecByte();;		//51重入
	
  	if(!c_uart->rx_byte_tmr) 							//收到一帧数据必须在超时时间内处理！！！
		  c_uart->rx_ct = 0;			                //last recv byte timeout! reset recv!!!
	c_uart->rx_byte_tmr = RX_RST_TIME;
	
	if (c_uart->recved_f)
		return;
 		
  	if(!c_uart->rx_ct)
  	{
  		if ((uart_rx_data != LEAD_BYTE)&& (uart_rx_data != LEAD_BYTETEST))
  			return;
	}
    if(!c_uart->rx_ct)
    {
  		if ((gu8_SystemBeginTime == 0)&&(uart_rx_data == LEAD_BYTETEST))
  			return;        
    }
	// if(c_uart->rx_ct == 1)
	// {
	// 	if ((uart_rx_data > UART_RX_BYTES) || (uart_rx_data == 0))
	// 	{//err
	// 		c_uart->rx_ct = 0;
	// 		return;
	// 	}
	// }

	c_uart->rx_buf[c_uart->rx_ct] = uart_rx_data;
	c_uart->rx_ct++;	


	if (c_uart->rx_ct >= 2)
		packet_len = 4;
	else
		return;

	if (c_uart->rx_ct >= packet_len)
	{
		c_uart->rx_ct = 0;   		//收到一帧
		c_uart->recved_f = true;    //isr_send_signal(CTRL_TASK_ID);给任务 CTRL_TASK_ID 发信号, 为了使用而使用		
	}
}
/****************************************
 * 函数名：	uart_byte_tmr_dn
 * 说明：	ms中断中调用 , 经过RX_RST_TIME没接收到1个字节，复位接收.
 * 输入：	UART_t 指针
 * 输出：	--
 ****************************************/
void uart_byte_tmr_dn(UART_t * c_uart)
{
    //uint8_t_dn(&c_uart->rx_byte_tmr);					//51重入警告
	if (c_uart->rx_byte_tmr)
		c_uart->rx_byte_tmr--;
}
/****************************************
 * 函数名：	uart_rest_err_tmr
 * 说明：	复位错误计数.
 * 输入：	UART_t 指针
 * 输出：	--
 ****************************************/
void uart_rest_err_tmr(UART_t * c_uart)
{
	c_uart->err_tmr_ct = 0;
}
/****************************************
 * 函数名：	uart_init
 * 说明：	uart初始化函数
 * 输入：	UART_t 指针, uart_id分配给UART_t指针对应的uart
 * 输出：	--
 ****************************************/
void uart_init(UART_t * c_uart, u8 uart_id)
{
	c_uart->uart_id   = uart_id;
    c_uart->sending_f = false;
    c_uart->recved_f  = false;
}
